package com.bawei.mdm2207alast.base

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import java.io.File

/**
 * 作者：赵亮
 * 时间：2024/12/16 16:49
 * 功能：ViewModel的封装
 */
abstract class BaseViewModel : ViewModel() {

    // 意图存储容器
    private val _channel = Channel<IUiIntent>(Channel.UNLIMITED)

    // 状态
    val uiState = MutableStateFlow<UiState>(OnLoading)

    // 消费意图
    init {
        viewModelScope.launch {
            _channel.receiveAsFlow().collect {
                handIntent(it)
            }
        }
    }

    // 消费意图
    abstract fun handIntent(it: IUiIntent)

    // 生产意图
    fun sendIntent(iUiIntent: IUiIntent) {
        viewModelScope.launch {
            _channel.send(iUiIntent)
        }
    }

    // 网络请求封装
    fun httpRequest(flow: Flow<*>) {
        viewModelScope.launch {
            flow.flowOn(Dispatchers.IO)
                .catch { uiState.value = OnError(it.message.toString()) }
                .collect { uiState.value = OnSuccess(it, refresh = "${Math.random()}") }
        }
    }

    // 数据库请求
    fun roomRequest(flow: Flow<*>) {
        viewModelScope.launch {
            flow.flowOn(Dispatchers.IO)
                .catch { uiState.value = OnError(it.message.toString()) }
                .collect {
                    if (it != null) {
                        uiState.value = OnSuccess(it)
                    } else {
                        uiState.value = OnError("操作失败")
                    }
                }
        }
    }

    // 扫描本地文件列表
    fun scanFile(file: File) {
        try {
            val files = file.listFiles()
            uiState.value = OnSuccess(files.toList())
        } catch (e:Exception) {
            uiState.value = OnError(e.message.toString())
        }
    }

}